Exploratory Data Analysis

Time Series Plot, Lag Plot, ACF, PACF, and Augmented Dickey-Fuller Test

Treasury Bill Constant Maturities Minus Federal Funds Rate

Code
df <- read_excel('data/data/sr_t-bill-rates.xlsx')
df$observation_date <- as.Date(df$observation_date)
columns <- c("T3MFF")

for (col in columns) {
  xts_data <- xts(df[, col], order.by = df$observation_date)
  ts_data <- ts(df[, col], start=c(1982, 1, 4), frequency=252)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value',ylim = c(-0.5,0.5))
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a decreasing trend, 
with an average value of -0.2 and a standard deviation of 0.28 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.05 .

The remainder component suggests random fluctuations, 
with an average value of 0 and a standard deviation of 0.28 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -8.271031 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -30.68056 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
df <- read_excel('data/data/sr_t-bill-rates.xlsx')
df$observation_date <- as.Date(df$observation_date)
columns <- c("T6MFF")

for (col in columns) {
  xts_data <- xts(df[, col], order.by = df$observation_date)
  ts_data <- ts(df[, col], start=c(1982, 1, 4), frequency=252)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value',ylim = c(-0.5,0.5))
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a decreasing trend, 
with an average value of -0.03 and a standard deviation of 0.28 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.04 .

The remainder component suggests random fluctuations, 
with an average value of 0 and a standard deviation of 0.29 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -7.594511 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -30.42139 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
df <- read_excel('data/data/sr_t-bill-rates.xlsx')
df$observation_date <- as.Date(df$observation_date)
columns <- c("T1YFF")
for (col in columns) {
  xts_data <- xts(df[, col], order.by = df$observation_date)
  ts_data <- ts(df[, col], start=c(1982, 1, 4), frequency=252)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value',ylim = c(-0.5,0.5))
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 0.13 and a standard deviation of 0.35 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.05 .

The remainder component suggests random fluctuations, 
with an average value of 0.01 and a standard deviation of 0.32 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -6.248758 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -29.35235 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.

Market Yield on U.S. Treasury Bonds Constant Maturity, Quoted on an Investment Basis

Code
columns <- c("DGS10")
df_10 <- df[!is.na(df[columns]) & df[columns] != "", ]

for (col in columns) {
  xts_data <- xts(df_10[, col], order.by = df_10$observation_date)
  ts_data <- ts(df_10[, col], start=c(1962, 1, 2), frequency=252)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 5.91 and a standard deviation of 2.95 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.04 .

The remainder component suggests random fluctuations, 
with an average value of 0 and a standard deviation of 0.34 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -2.358925 
P-value: 0.4262639 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -22.84948 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
columns <- c("DGS20")
df_20 <- df[!is.na(df[columns]) & df[columns] != "", ]

for (col in columns) {
  xts_data <- xts(df_20[, col], order.by = df_20$observation_date)
  ts_data <- ts(df_20[, col], start=c(1962, 1, 2), frequency=252)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 5.94 and a standard deviation of 2.87 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.04 .

The remainder component suggests random fluctuations, 
with an average value of 0 and a standard deviation of 0.31 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -2.016143 
P-value: 0.5715748 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -22.66937 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
columns <- c("DGS30")
df_30 <- df[!is.na(df[columns]) & df[columns] != "", ]

for (col in columns) {
  xts_data <- xts(df_30[, col], order.by = df_30$observation_date)
  ts_data <- ts(df_30[, col], start=c(1977, 2, 15), frequency=252)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 6.26 and a standard deviation of 3.02 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.05 .

The remainder component suggests random fluctuations, 
with an average value of 0 and a standard deviation of 0.32 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -3.1987 
P-value: 0.08796191 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -20.60433 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.

Economic Indicators

Code
columns <- c("FEDFUNDS")
df_ffr <- df[!is.na(df[columns]) & df[columns] != "", ]
for (col in columns) {
  xts_data <- xts(df_ffr[, col], order.by = df_ffr$observation_date)
  ts_data <- ts(df_ffr[, col], start=c(1962, 2, 1), frequency=12)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 4.88 and a standard deviation of 3.61 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.07 .

The remainder component suggests random fluctuations, 
with an average value of -0.01 and a standard deviation of 0.77 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -2.777681 
P-value: 0.2491291 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -6.888716 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
columns <- c("MORTGAGE30")
df_mort <- df[!is.na(df[columns]) & df[columns] != "", ]
for (col in columns) {
  xts_data <- xts(df_mort[, col], order.by = df_mort$observation_date)
  ts_data <- ts(df_mort[, col], start=c(1971, 4, 2), frequency=52)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 7.75 and a standard deviation of 3.25 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.06 .

The remainder component suggests random fluctuations, 
with an average value of 0 and a standard deviation of 0.33 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -2.183748 
P-value: 0.5005302 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -14.02196 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
columns <- c("CPI")
df_cpi <- df[!is.na(df[columns]) & df[columns] != "", ]
for (col in columns) {
  xts_data <- xts(df_cpi[, col], order.by = df_cpi$observation_date)
  ts_data <- ts(df_cpi[, col], start=c(1962, 2, 1), frequency=12)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value',ylim = c(-0.5,0.5))
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 140.28 and a standard deviation of 77.1 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.14 .

The remainder component suggests random fluctuations, 
with an average value of -0.01 and a standard deviation of 0.67 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -1.625921 
P-value: 0.736648 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -5.055112 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
columns <- c("GDP")
df_gdp <- df[!is.na(df[columns]) & df[columns] != "", ]
for (col in columns) {
  xts_data <- xts(df_gdp[, col], order.by = df_gdp$observation_date)
  ts_data <- ts(df_gdp[, col], start=c(1962, 10, 1), frequency=4)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 11515.29 and a standard deviation of 5265.6 .

The seasonal component suggests a repeating pattern, 
with an average value of -0.41 and a standard deviation of 41.98 .

The remainder component suggests random fluctuations, 
with an average value of -0.16 and a standard deviation of 120.32 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -1.773162 
P-value: 0.670995 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -7.392571 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
columns <- c("UER")
df_uemp <- df[!is.na(df[columns]) & df[columns] != "", ]
for (col in columns) {
  xts_data <- xts(df_uemp[, col], order.by = df_uemp$observation_date)
  ts_data <- ts(df_uemp[, col], start=c(1962, 2, 1), frequency=12)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 5.98 and a standard deviation of 1.59 .

The seasonal component suggests a repeating pattern, 
with an average value of 0 and a standard deviation of 0.1 .

The remainder component suggests random fluctuations, 
with an average value of 0 and a standard deviation of 0.56 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -3.162679 
P-value: 0.09436521 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -8.081753 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.
Code
columns <- c("USDIDX")
df_usd <- df[!is.na(df[columns]) & df[columns] != "", ]
for (col in columns) {
  xts_data <- xts(df_usd[, col], order.by = df_usd$observation_date)
  ts_data <- ts(df_usd[, col], start=c(2018, 9, 17), frequency=365)
  decomposed <- decompose(ts_data)
  
  plot(decomposed$x, main = paste("Original Time Series:", col), xlab = 'Date', ylab = 'Value')
  plot(decomposed$trend, main = "Trend Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$seasonal, main = "Seasonal Component", xlab = 'Date', ylab = 'Value')
  plot(decomposed$random, main = "Remainder Component", xlab = 'Date', ylab = 'Value')
  lag.plot(ts_data, lags=1, do.lines=FALSE, main="Lag Plot")
  acf_data <- acf(ts_data, main=paste("ACF Plot:", col))
  dacf_data <- pacf(ts_data, main=paste("PACF Plot:", col))
  diff_ts_data <- diff(ts_data)
  acf(diff_ts_data, main=paste("ACF After Differencing:", col))
  pacf(diff_ts_data, main=paste("PACF After Differencing:", col))
  }

Code
for (col in columns) {
  trend <- decomposed$trend
  if (!is.null(trend)) {
    trend_mean <- mean(trend, na.rm = TRUE)
    trend_sd <- sd(trend, na.rm = TRUE)
    trend_trend <- ifelse(trend_mean > 0, "increasing", "decreasing")
    cat("The trend component suggests a", trend_trend, "trend, \nwith an average value of", round(trend_mean, 2), "and a standard deviation of", round(trend_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible trend component.\n\n")
  }
  
  seasonal <- decomposed$seasonal
  if (!is.null(seasonal)) {
    seasonal_mean <- mean(seasonal, na.rm = TRUE)
    seasonal_sd <- sd(seasonal, na.rm = TRUE)
    cat("The seasonal component suggests a repeating pattern, \nwith an average value of", round(seasonal_mean, 2), "and a standard deviation of", round(seasonal_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible seasonal component.\n\n")
  }
  
  remainder <- decomposed$random
  if (!is.null(remainder)) {
    remainder_mean <- mean(remainder, na.rm = TRUE)
    remainder_sd <- sd(remainder, na.rm = TRUE)
    cat("The remainder component suggests random fluctuations, \nwith an average value of", round(remainder_mean, 2), "and a standard deviation of", round(remainder_sd, 2), ".\n\n")
  } else {
    cat("There is no discernible remainder component.\n\n")
  }
  
  if (decomposed$type == "multiplicative") {
    cat("The time series appears to be multiplicative.\n\n")
  } else {
    cat("The time series appears to be additive.\n\n")
  }
  
  adf_test <- adf.test(ts_data)
  cat("Augmented Dickey-Fuller Test Results:\n")
  cat("Test Statistic:", adf_test$statistic, "\n")
  cat("P-value:", adf_test$p.value, "\n")
  cat("Critical Values:", adf_test$critical, "\n")
  if (adf_test$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")}

  adf_test_diff <- adf.test(diff_ts_data)
  cat("Augmented Dickey-Fuller Test Results After Differencing:\n")
  cat("Test Statistic:", adf_test_diff$statistic, "\n")
  cat("P-value:", adf_test_diff$p.value, "\n")
  cat("Critical Values:", adf_test_diff$critical, "\n")
  if (adf_test_diff$p.value < 0.05) {
    cat("The time series is stationary based on the ADF test.\n\n")
  } else {
    cat("The time series is not stationary based on the ADF test.\n\n")
  }
  }
The trend component suggests a increasing trend, 
with an average value of 116.8 and a standard deviation of 2.12 .

The seasonal component suggests a repeating pattern, 
with an average value of 0.08 and a standard deviation of 1.4 .

The remainder component suggests random fluctuations, 
with an average value of 0.29 and a standard deviation of 2.27 .

The time series appears to be additive.

Augmented Dickey-Fuller Test Results:
Test Statistic: -1.982863 
P-value: 0.5855674 
Critical Values: 
The time series is not stationary based on the ADF test.

Augmented Dickey-Fuller Test Results After Differencing:
Test Statistic: -10.6259 
P-value: 0.01 
Critical Values: 
The time series is stationary based on the ADF test.